package com.lcc.lynx.security.interceptor;

import com.lcc.lynx.security.annotation.Permission;
import com.lcc.lynx.common.exception.e.UnauthorizedException;
import com.lcc.lynx.security.Session;
import com.lcc.lynx.security.annotation.NoAuthorization;
import com.lcc.lynx.security.pojo.UserInfo;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import java.lang.reflect.Method;

/**
 * 权限拦截器
 * @author lcc
 * @date 2025/2/25 11:02
 */
@Component
public class PermissionInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 检查是否为方法处理器
        if (handler instanceof HandlerMethod handlerMethod) {
            Method method = handlerMethod.getMethod();
            Class<?> controllerClass = handlerMethod.getBeanType();

            // 获取当前登录用户信息
            UserInfo loginUser = Session.getUserInfo();

            // 未登录，管理员，直接放行
            if (loginUser == null || loginUser.isAdmin() || !loginUser.isLogin()) {
                return true;
            }

            // 获取方法上的@Permission注解
            Permission psn = method.getAnnotation(Permission.class);
            if (psn == null) {
                return true;
            }

            // 如果方法或控制器类上有@NoAuthorization注解，直接放行
            if (controllerClass.getAnnotation(NoAuthorization.class) != null || method.getAnnotation(NoAuthorization.class) != null) {
                return true;
            }

            // 处理权限值
            String[] values = psn != null ? psn.value() : new String[0];
            // 获取控制器类上的@Permission注解
            Permission permission = controllerClass.getAnnotation(Permission.class);
            // 获取控制器类上的@RequestMapping注解作为前缀
            RequestMapping reqMapping = controllerClass.getAnnotation(RequestMapping.class);
            for (String value : values) {
                if (value.startsWith(":")) {
                    if (permission != null) {
                        value = permission.value() + value;
                    } else {
                        if (reqMapping != null && reqMapping.value().length > 0) {
                            String str = reqMapping.value()[0];
                            if (str.startsWith("/")) {
                                str = str.substring(1);
                            }
                            value = str.replace("/", ":") + value;
                        }
                    }
                }

                // 检查用户是否拥有该权限
                if (!loginUser.getPermissions().contains(value)) {
                    throw new UnauthorizedException("未授权：" + value);
                }
            }
        }
        // 放行请求
        return true;
    }
}
